package com.atguigu.gmall.wms.listener;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.consts.GmallConsts;
import com.atguigu.gmall.wms.service.WareSkuService;
import com.atguigu.gmall.wms.vo.SkuLockVO;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class WmsMqListener {
    @Resource
    RabbitTemplate rabbitTemplate;
    @Resource
    WareSkuService wareSkuService;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "wms.queue2"),
                    exchange = @Exchange(value = GmallConsts.MQ_ORDER_EXCHANGE
                            ,type = ExchangeTypes.TOPIC),
                    key = "trade.success"
            )
    })
    public void paySuccess(Map<String,Object> map , Message message, Channel channel) throws IOException {
        try {
            String orderToken = map.get("orderToken").toString();
            //查询锁定库存数据
            String lockSucJson = stringRedisTemplate.opsForValue().get(GmallConsts.SKU_LOCK_SUCCESS_PREFIX + orderToken);
            if(StringUtils.isEmpty(lockSucJson)){
                channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
                return;
            }
            List<SkuLockVO> skuLockVOS = JSON.parseArray(lockSucJson, SkuLockVO.class);
            skuLockVOS.forEach(skuLockVO -> {
                // update ware_sku_stock set sales=sales+count , stock = stock-count, stock_locked = stock_locked-count where id = wareskuid
                wareSkuService.updateStockAndSales(skuLockVO);

            });
            //
            stringRedisTemplate.delete(GmallConsts.SKU_LOCK_SUCCESS_PREFIX + orderToken);

            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            //e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //消息第二次消费失败: 丢弃消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                //消息第一次消费失败
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }




    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "wms.queue"),
                    exchange = @Exchange(value = GmallConsts.MQ_ORDER_EXCHANGE
                            ,type = ExchangeTypes.TOPIC),
                    key = "stock.unlock"
            )
    })
    public void releaseStock(String orderToken , Message message, Channel channel) throws IOException {
        try {
            //如果orderToken的订单存在：需要关单
            rabbitTemplate.convertAndSend(GmallConsts.MQ_ORDER_EXCHANGE,
                    "oms.order.close",orderToken);
            //释放库存
            wareSkuService.batchReleaseStock(orderToken);
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            //e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //消息第二次消费失败: 丢弃消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                //消息第一次消费失败
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            }
        }
    }

}
